package com.lcf.system.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import com.lcf.framework.enums.RedisCachePrefixEnum;
import com.lcf.framework.exception.SysException;
import com.lcf.framework.utils.RedisCacheUtils;
import com.lcf.framework.utils.UserUtils;
import com.lcf.system.dao.SysUserRoleDao;
import com.lcf.system.dto.userRole.SysUserRoleDTO;
import com.lcf.system.entity.SysRole;
import com.lcf.system.entity.SysUserRole;
import com.lcf.system.manager.SysRoleManager;
import com.lcf.system.manager.SysUserManager;
import com.lcf.system.service.SysUserRoleService;
import com.lcf.system.vo.userRole.SysUserRoleVO;
import jakarta.annotation.Resource;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 用户与角色(SysUserRole)表服务实现类
 *
 * @author lcf
 * @since 2025-02-25 12:30:27
 */
@Service("sysUserRoleService")
public class SysUserRoleServiceImpl extends ServiceImpl<SysUserRoleDao, SysUserRole> implements SysUserRoleService {
    @Resource
    private SysUserManager sysUserManager;
    @Resource
    private RedisCacheUtils redisCacheUtils;
    @Resource
    private SysRoleManager sysRoleManager;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void setUserRole(long userId, SysUserRoleDTO sysUserRole) {
        sysUserManager.checkId(userId);

        Db.lambdaUpdate(SysUserRole.class).eq(SysUserRole::getUserId, userId).remove();

        List<SysRole> roleList = Db.lambdaQuery(SysRole.class).in(SysRole::getId, sysUserRole.getRoleIdList()).list();
        if (CollectionUtils.isEmpty(roleList)) {
            throw new SysException("角色不存在");
        }

        //检查是否至少有一位管理员
        sysRoleManager.checkLastAdmin(userId, roleList);

        List<SysUserRole> list = roleList.stream().map(x -> new SysUserRole(userId, x.getId())).toList();
        saveBatch(list);

        //删除用户角色缓存
        long tenantId = UserUtils.getTenantId();
        redisCacheUtils.del(RedisCachePrefixEnum.USER_ROLE.getKey(userId + ":" + tenantId));
    }

    @Override
    public List<SysUserRoleVO> getUserRole(long userId) {
        return Db.lambdaQuery(SysUserRole.class)
                .eq(SysUserRole::getUserId, userId)
                .list()
                .stream()
                .map(x -> new SysUserRoleVO(x.getRoleId()))
                .toList();
    }
}

